package org.funtester.performance.books.chapter10.section4;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.function.Supplier;

/**
 * 自定义对象池
 * @param <F> 对象池中对象的类型
 */
public class FunPool<F> {

    /**
     * 对象池中对象的创建方法
     */
    public Supplier<F> supplier;

    /**
     * 对象池存放对象的队列
     */
    public LinkedBlockingQueue<F> pool = new LinkedBlockingQueue<F>();

    public FunPool(Supplier<F> supplier) {
        this.supplier = supplier;
    }

    /**
     * 从对象池中借出对象，如果对象池中没有对象，则创建新对象
     * @return
     */
    public F borrow() {
        F f = pool.poll();
        if (f == null) {
            f = supplier.get();
        }
        return f;
    }

    /**
     * 归还对象
     * @param f 借出的对象，或者外部创建的对象
     */
    public void back(F f) {
        boolean offer = pool.offer(f);
        if (!offer) {
            f = null;
        }
    }

    /**
     * 获取对象池中对象数量
     * @return
     */
    public int size() {
        return pool.size();
    }

    /**
     * 整理对象池，保留指定数量的对象池
     * @param size 保留的对象池大小
     */
    public void trimQueue(int size) {
        while (true) {
            if (size() <= size) break;
            pool.poll();
        }
    }

}
